package pe.com.pgn.consolidadorventas.servidorcentral.dao.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import pe.com.pgn.consolidadorventas.servidorcentral.dao.ServidorCentralDao;
import pe.com.pgn.consolidadorventas.servidorcentral.dbo.Estacion;
import pe.com.pgn.consolidadorventas.servidorcentral.util.ArchivosUtil;
import pe.com.pgn.consolidadorventas.servidorcentral.util.Constantes;
import pe.com.pgn.consolidadorventas.servidorcentral.util.FechasUtil;
import pe.com.pgn.consolidadorventas.servidorcentral.util.LoggerUtil;
import pe.com.pgn.consolidadorventas.servidorcentral.util.MessengerSOAP;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.GnvRptaConsultaVenta;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.factory.GnvXmlToObjectFactory;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.util.WsConstantes;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.util.WsTimeOutController;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.util.WsTimeOutThread;

public class ServidorCentralGnvDaoImpl implements ServidorCentralDao {

	static Logger logger = Logger.getLogger(ServidorCentralGnvDaoImpl.class);

    Constantes constantes;
    
    WsConstantes wsConstantes;
    
	public GnvRptaConsultaVenta consultarInformacionVentasPorDia(Estacion e,String fecha, int tipoCombustible) {
		
		Calendar cx;

    	String ip = e.getIp();
    	String puerto = e.getPuerto();
    	
		GnvRptaConsultaVenta resultadoOperacion = new GnvRptaConsultaVenta();
		
		//Inicializamos el SAXBuilder
		SAXBuilder conversor = new SAXBuilder();
        conversor.setExpandEntities(true);
        conversor.setIgnoringElementContentWhitespace(true);
        
        LoggerUtil.info(logger,"Inicializa mensajero SOAP");
		//Creamos el mensajero
        MessengerSOAP mensajero = new MessengerSOAP(Constantes.PROTOCOLO,ip,puerto,
	    							  Constantes.CONTEXTO,
	    							  Constantes.WEBSERVICE,
	    							  Constantes.NAMESPACE);
		
		mensajero.setUsarCifrado(wsConstantes.getUsarCifrado());
	   
		//Inicializamos su conexion
		mensajero.inicializarRutaConexion();
		
		//Inicializamos cabecera para seguridad
		mensajero.inicializarCabeceraMensaje(wsConstantes.getUsuario(),wsConstantes.getClave());
		
		//Seteamos los parametros
		List<String> parametrosWs = new ArrayList<String>();
		parametrosWs.add("fecha");
		parametrosWs.add("tipoCombustible");
		
		List<String> valoresParametrosWs = new ArrayList<String>();
		valoresParametrosWs.add(fecha);
		valoresParametrosWs.add(String.valueOf(tipoCombustible));
		
		//Inicializamos el mensaje
		
		mensajero.inicializarCuerpoMensaje(Constantes.FN_VENTAS_POR_DIA, parametrosWs, valoresParametrosWs);
		
		//Enviamos el mensaje y recibimos la respuesta
		
		LoggerUtil.info(logger,"Envia mensaje SOAP");
		
		//Colocamos el timeout
		int timeOut = 0;
		try{
			timeOut = e.getTimeOutWs();
		}catch(Exception ex){
			timeOut = Constantes.DEFAULT_TIMEOUT;
		}
		
		WsTimeOutThread timeThread = new WsTimeOutThread();
		timeThread.setMessenger(mensajero);
		WsTimeOutController wsc = new WsTimeOutController(timeOut,timeThread);
		
		String solucion = wsc.enviarMensaje();
		//String solucion = mensajero.enviarMensaje(Constantes.RPTA_FN_VENTAS_POR_DIA);
		
		LoggerUtil.info(logger,"Fin llamada SOAP");
		
		//Preparamos la llamada para el archivado de la respuesta
		String rutaGuardar = constantes.getCarpetaGnv();
		String formatoFechaGuardar = "";
		List<String> errores = null;
		
		try{
    		String valoresFecha[] = fecha.split("\\/");
    		formatoFechaGuardar = valoresFecha[2]+valoresFecha[1]+valoresFecha[0];
    		rutaGuardar = rutaGuardar + e.getCodEstacion() + formatoFechaGuardar;
		}catch(ArrayIndexOutOfBoundsException ex){
			LoggerUtil.error(logger, ex.getMessage());
			rutaGuardar = "";
		}
		
		if(solucion.equals("-1") || solucion.equals(Constantes.TIMEOUT_EXCEDIDO)){
			
			//No hubo comunicacion con la estacion
			resultadoOperacion.setDia(fecha);
			resultadoOperacion.setTipoRespuesta(-1);
			
			String mensajeError = "";
			if(solucion.equals("-1")){
				mensajeError = "No hay comunicacion con la estacion : "+ip+":"+puerto;
			}else{
				mensajeError = "Timeout excedido para estacion : "+ip+":"+puerto;
			}
			LoggerUtil.error(logger,mensajeError);
			
			resultadoOperacion.setMensajeError(mensajeError);
			
			//Guardamos el mensaje de error
 		    if(!rutaGuardar.equals("")){
            	rutaGuardar = rutaGuardar + "_err.txt";
            	errores = new ArrayList<String>();
            	cx = Calendar.getInstance();
            	errores.add(resultadoOperacion.getMensajeError()+" ("+FechasUtil.formatearDateTimeToString(cx.getTime())+")");
            	ArchivosUtil.guardarArchivo(rutaGuardar,errores);
 		    }
			
		}else{
			
			StringReader lectura= new StringReader(solucion);
	        BufferedReader archivo= new BufferedReader(lectura);
	        
	        //Convertimos la lectura a documento
	        
	        try{
	        	LoggerUtil.info(logger,"Inicia construccion documento XML");
	        	
	            Document doc = conversor.build(archivo);
	            Element raiz = doc.getRootElement();
	            
	        	LoggerUtil.info(logger,"Fin construccion documento XML");
	            
	            int tipoRespuesta = Integer.parseInt(raiz.getAttributeValue("tipoRespuesta"));
	            resultadoOperacion.setTipoRespuesta(tipoRespuesta);  
	            resultadoOperacion.setDia(raiz.getAttributeValue("dia"));
	            resultadoOperacion.setCodEstacion(raiz.getAttributeValue("codEstacion"));
	            
	            //Si hubo error en la llamada al archivo
	            if(tipoRespuesta == 0 || tipoRespuesta == -1){
	            	resultadoOperacion.setMensajeError(raiz.getChildText("mensajeError"));
	            	
	            	//Guardamos el mensaje de error
         		    if(!rutaGuardar.equals("")){
    	            	rutaGuardar = rutaGuardar + "_err.txt";
    	            	errores = new ArrayList<String>();
    	            	errores.add(resultadoOperacion.getMensajeError());
    	            	ArchivosUtil.guardarArchivo(rutaGuardar,errores);
         		    }
	            	
	            }else{
	            	if(!rutaGuardar.equals("")){
	            		String rutaZip = rutaGuardar + ".zip";
	            		String rutaDescomprimido = rutaGuardar + ".txt";
	            		GnvXmlToObjectFactory.parsearArchivoZipeado(rutaZip, rutaDescomprimido, raiz, resultadoOperacion);
	            	}
	            }
	            
	        }catch(JDOMException ex){
	        	LoggerUtil.error(logger,ex.getMessage());
	        }catch (IOException ioe) {
	        	LoggerUtil.error(logger,ioe.getMessage());
	        }
		}
		
		return resultadoOperacion;
	}

	public Constantes getConstantes() {
		return constantes;
	}

	public void setConstantes(Constantes constantes) {
		this.constantes = constantes;
	}

	public WsConstantes getWsConstantes() {
		return wsConstantes;
	}

	public void setWsConstantes(WsConstantes wsConstantes) {
		this.wsConstantes = wsConstantes;
	}

}